import axios from 'axios';

// 实例
const request = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,
  timeout: 5000,
});

// 添加请求拦截器
request.interceptors.request.use(
  // 获取配置
  function (config) {
    // 请求地址携带时间戳
    const _t = new Date().getTime();
    if (config.url.indexOf('?') > -1) {
      config.url += `&_t=${_t}`;
    } else {
      config.url += `?_t=${_t}`;
    }
    // 添加token
    config.headers['token'] = localStorage.getItem('token') || '';
    // 在发送请求之前做些什么
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 添加响应拦截器
request.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    if (response.status === 200) {
      return Promise.resolve(response.data);
    } else {
      return Promise.reject(response);
    }
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          error.message = '请求错误';
          break;
        case 401:
          error.message = '未授权，请登录';
          break;
        case 403:
          error.message = '拒绝访问';
          break;
        case 404:
          error.message = `请求地址出错: ${error.response.config.url}`;
          break;
        case 405:
          error.message = '请求方法不允许';
          break;
        case 408:
          error.message = '请求超时';
          break;
        case 500:
          error.message = '服务器内部错误';
          break;
        case 501:
          error.message = '网络未实现';
          break;
        case 502:
          error.message = '网络错误';
          break;
        case 503:
          error.message = '服务不可用';
          break;
        case 504:
          error.message = '网络超时';
          break;
        case 505:
          error.message = 'HTTP版本不受支持';
          break;
        default:
          error.message = `未知错误(${error.response.status})!`;
      }
    } else {
      error.message = '网络异常，请稍后重试！';
    }
    return Promise.reject(error);
  }
);

/**
 * get请求
 * @param {String} url 请求地址
 * @param {Object} params 请求参数
 */
export function get(url, params) {
  return new Promise((resolve, reject) => {
    request({
      url: url || '',
      method: 'get',
      params: params || {},
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

/**
 * post请求
 * @param {String} url 请求地址
 * @param {Object} params 请求参数
 */
export function post(url, params) {
  return new Promise((resolve, reject) => {
    request({
      url: url || '',
      method: 'post',
      data: params || {},
    })
      .then((response) => {
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

/**
 * post请求
 * @param {String} url 请求地址
 * @param {Object} params 请求参数
 */
export function post1(url, params, fn) {
  const controller = new AbortController();
  const signal = controller.signal; // 获取 signal 对象
  return new Promise((resolve, reject) => {
    request({
      url: url || '',
      method: 'post',
      data: params || {},
      signal, // 将 signal 传递给服务函数
    })
      .then((response) => {
        // 如果提供了 onCancel 回调，则传递取消函数
        if (typeof fn === 'function') {
          // 如果是一个函数，则直接调用传一个取消方法给 这个方法
          // 所以只要传进来是方法，就会直接传一个参数并直接触发这个函数
          // 那传过来的这个方法就会接收到一个参数（就是取消函数() => controller.abort()）
          // 在调用uploadFile就可以拿到这个参数
          fn(() => controller.abort()); // 调用 onCancel 时传入取消函数
        }
        resolve(response);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

export default {
  get,
  post,
  post1,
};
